package com.vogue.supplymall.admin.business.domain.biz.impl;

import com.vogue.supplymall.account.domain.model.AdminUser;
import com.vogue.supplymall.account.domain.model.BaseRegistinfo;
import com.vogue.supplymall.account.domain.service.BaseCodeService;
import com.vogue.supplymall.account.domain.service.BaseRegistinfoService;
import com.vogue.supplymall.admin.business.domain.biz.OpenOrganBiz;
import com.vogue.supplymall.admin.business.domain.model.AdminAccountBalance;
import com.vogue.supplymall.admin.business.domain.model.AdminAccountDiscount;
import com.vogue.supplymall.admin.business.domain.model.AdminConsumeProduct;
import com.vogue.supplymall.admin.business.domain.model.AdminOrgan;
import com.vogue.supplymall.admin.business.domain.model.AdminPlatform;
import com.vogue.supplymall.admin.business.domain.model.AdminRecharge;
import com.vogue.supplymall.admin.business.domain.service.AdminAccountBalanceService;
import com.vogue.supplymall.admin.business.domain.service.AdminAccountDiscountService;
import com.vogue.supplymall.admin.business.domain.service.AdminConsumeProductService;
import com.vogue.supplymall.admin.business.domain.service.AdminOrganService;
import com.vogue.supplymall.admin.business.domain.service.AdminPlatformService;
import com.vogue.supplymall.admin.business.domain.service.AdminRechargeService;
import com.vogue.supplymall.common.domain.dto.admin.OrganManagementInfo;
import com.vogue.supplymall.common.domain.dto.admin.OrganSearchInfo;
import com.vogue.supplymall.common.domain.dto.admin.PlatformInfo;
import com.vogue.supplymall.cross.domain.service.AdminManagementService;
import com.vogue.supplymall.entmanagement.domain.model.LicenceApply;
import com.vogue.supplymall.entmanagement.domain.model.LicenceApplyDetail;
import com.vogue.supplymall.entmanagement.domain.service.LicenceApplyDetailService;
import com.vogue.supplymall.entmanagement.domain.service.LicenceApplyService;
import com.vogue.supplymall.match.domain.model.MatchOrgan;
import com.vogue.supplymall.match.domain.service.MatchOrganService;
import com.vogue.supplymall.shop.domain.service.ShopService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * The type open organ biz.
 * 开通集团的业务处理service
 *
 * @aouthor: zhangliang
 * @date: Create in 2018-04-27
 */
@Service("openOrganBiz")
public class OpenOrganBizImpl implements OpenOrganBiz {
    /**
     * The constant log.
     */
    public static final Logger LOGGER_OPENORGANBIZIMPL = LoggerFactory.getLogger(OpenOrganBizImpl.class);

    @Resource
    private BaseCodeService baseCodeService;
    @Resource
    private BaseRegistinfoService baseRegistinfoService;
    @Resource
    private AdminOrganService adminOrganService;
    @Resource
    private AdminPlatformService adminPlatformService;
    @Resource
    private AdminConsumeProductService adminConsumeProductService;
    @Resource
    private AdminRechargeService adminRechargeService;
    @Resource
    private AdminAccountDiscountService adminAccountDiscountService;
    @Resource
    private LicenceApplyService licenceApplyService;
    @Resource
    private LicenceApplyDetailService licenceApplyDetailService;
    @Resource
    private MatchOrganService matchOrganService;
    @Resource
    private AdminManagementService adminManagementService;
    @Resource
    private ShopService shopService;
    @Resource
    private AdminAccountBalanceService adminAccountBalanceService;

    @Override
    public Map<String, Object> getOpenOrganList(OrganSearchInfo organSearchInfo) {
        LOGGER_OPENORGANBIZIMPL.info(" 查询未开通集团 ");
        if (organSearchInfo.getPages() == 0) {
            return null;
        }
        organSearchInfo.setStart((organSearchInfo.getPages() - 1) * organSearchInfo.getLength());
        // 开通集团-查询注册账号已申请但没开通的集团
        Map<String, Object> data = new HashMap<>();
        List<Map<String, Object>> baseInfo;
        Long totalPages = baseCodeService.findValidOrganCount(organSearchInfo);
        data.put("totalPages", totalPages);
        if (totalPages > 0L) {
            baseInfo = baseCodeService.findValidOrgan(organSearchInfo);
            for (Map<String, Object> map : baseInfo) {
                if (!map.containsKey("besellerdate")) {
                    map.put("besellerdate", "");
                }
            }
            data.put("lists", baseInfo);
        }
        return data;
    }

    @Override
    @Transactional
    public void openOrgan(OrganManagementInfo info, AdminUser userInfo) {
        List<Map<String, Object>> organs = adminOrganService.getAdminOrganBySyscode(info.getSyscode());
        if (organs.size() == 0) {
            // 保存开通集团信息
            Long organId = saveAdminOrgan(info, userInfo);
            info.setOrganid(organId);
            // 保存计费产品信息
            Long consumeid = saveAdminConsumeProduct(info, userInfo);
            info.setConsumeid(consumeid);
            // 保存集团入住平台信息
            Integer platform = saveAdminPlatform(info, userInfo);
            // 没有充值金额不添加充值记录
            if (StringUtils.isNotEmpty(info.getAmount()) || !"0".equals(info.getAmount())) {
                // 保存充值记录
                saveAdminRecharge(info, userInfo);
            }
            if (StringUtils.isNotEmpty(info.getDiscount()) || !"0".equals(info.getDiscount())) {
                // 保存充值优惠记录
                saveAdminDiscount(info, userInfo);
            }
            // 保存集团账本信息
            saveAdminAccountBalance(info, userInfo, 0);
            saveAdminAccountBalance(info, userInfo, 1);
            // 更新用户注册信息
            updateRegistInfo(info);
            // 更新机构信息
            String selectSql = "syscodeid = #{syscodeid} and type = 1 and tendid = #{tendid}";
            Map<String, Object> para = new HashMap<>();
            para.put("syscodeid", info.getSyscodeid());
            para.put("tendid", platform);
            List<MatchOrgan> organList = matchOrganService.selectByWhr0(selectSql, para);
            if (organList.size() > 0) {
                MatchOrgan organ = organList.get(0);
                organ.setDisabledflag(false);
                organ.setModifyDate(new Date());
                matchOrganService.update(organ);
                LOGGER_OPENORGANBIZIMPL.info("更新机构信息，企业更新为开通，syscodeid：" + organ.getSyscodeid());
            }
        }
    }

    /**
     * 更新用户注册信息
     * 开通集团后，注册信息为可用
     *
     * @param info info
     */
    private void updateRegistInfo(OrganManagementInfo info) {
        BaseRegistinfo baseRegistinfo = baseRegistinfoService.get(info.getRid());
        if (null != baseRegistinfo) {
            baseRegistinfo.setDisabledflag(false);
            baseRegistinfoService.update(baseRegistinfo);
        }
    }

    /**
     * 保存集团基本信息
     *
     * @param info info
     * @param userInfo userInfo
     * @return Long
     */
    private Long saveAdminOrgan(OrganManagementInfo info, AdminUser userInfo) {
        AdminOrgan adminOrgan = new AdminOrgan();
        adminOrgan.setOrganname(info.getOrgname());
        adminOrgan.setSyscode(info.getSyscode());
        adminOrgan.setSyscodeid(info.getSyscodeid());
        adminOrgan.setTel(info.getTel());
        adminOrgan.setMemo(info.getMemo());
        adminOrgan.setTpsystem(Integer.valueOf(info.getTpsystem()));
        adminOrgan.setUpdateuser(userInfo.getLoginname());
        adminOrgan.setUpdateuserid(userInfo.getId());
        adminOrgan = adminOrganService.save(adminOrgan);
        LOGGER_OPENORGANBIZIMPL.info("保存集团信息，集团名称:" + adminOrgan.getOrganname());
        return adminOrgan.getId();
    }

    /**
     * 保存集团计费产品信息
     *
     * @param info info
     * @param userInfo userInfo
     * @return Long
     */
    private Long saveAdminConsumeProduct(OrganManagementInfo info, AdminUser userInfo) {
        AdminConsumeProduct adminBilling = new AdminConsumeProduct();
        adminBilling.setOrganid(info.getOrganid());
        adminBilling.setConsumetype(info.getBillingtype());
        adminBilling.setCommission(new BigDecimal(info.getCommission()));
        adminBilling.setSyscodeid(info.getSyscodeid());
        // 如果计费产品类型是按单扣点
        if (info.getBillingtype() == 3) {
            adminBilling.setCost(BigDecimal.ZERO);
            adminBilling.setSingleratio(new BigDecimal(info.getSingleratio()));
            adminBilling.setMinimum(new BigDecimal(info.getMinimum()));
            adminBilling.setUpperlimit(new BigDecimal(info.getUpperlimit()));
        } else {
            adminBilling.setCost(new BigDecimal(info.getCost()));
            adminBilling.setSingleratio(BigDecimal.ZERO);
            adminBilling.setUpperlimit(BigDecimal.ZERO);
            adminBilling.setMinimum(BigDecimal.ZERO);
        }
        adminBilling.setOwner(info.getOwner());
        adminBilling.setDisabledflag(false);
        adminBilling.setValidtype(0);
        if (StringUtils.isNotEmpty(info.getMemo())) {
            adminBilling.setMemo(info.getMemo());
        } else {
            adminBilling.setMemo("");
        }
        adminBilling.setUpdateuser(userInfo.getLoginname());
        adminBilling.setUpdateuserid(userInfo.getId());
        adminBilling = adminConsumeProductService.save(adminBilling);
        LOGGER_OPENORGANBIZIMPL.info("保存集团计费产品信息，syscodeid:" + adminBilling.getSyscodeid());
        return adminBilling.getId();
    }

    /**
     * 集团入住平台基本信息
     *
     * @param info info
     * @param userInfo userInfo
     * @return Integer
     */
    private Integer saveAdminPlatform(OrganManagementInfo info, AdminUser userInfo) {
        List<PlatformInfo> platformInfo = info.getPlatformInfo();
        Integer platCodes = 0;
        for (PlatformInfo platform : platformInfo) {
            if (platform.getIsbind()) {
                platCodes = Integer.valueOf(platform.getChannel());
            }

            AdminPlatform adminPlatform = new AdminPlatform();
            adminPlatform.setIsbind(platform.getIsbind());
            adminPlatform.setOrganid(info.getOrganid());
            adminPlatform.setSyscodeid(info.getSyscodeid());
            adminPlatform.setPlatform(Integer.valueOf(platform.getChannel()));
            adminPlatform.setUpdateuser(userInfo.getLoginname());
            adminPlatform.setUpdateuserid(userInfo.getId());
            LOGGER_OPENORGANBIZIMPL.info("保存集团入住平台基本信息，syscodeid:" + info.getSyscodeid());
            adminPlatformService.save(adminPlatform);
        }
        return platCodes;
    }

    /**
     * 保存集团账本信息
     * 包括现金和信用
     *
     * @param info info
     * @param userInfo userInfo
     * @param type type
     */
    private void saveAdminAccountBalance(OrganManagementInfo info, AdminUser userInfo, Integer type) {
        AdminAccountBalance accountBalance = new AdminAccountBalance();
        accountBalance.setOrganid(info.getOrganid());
        BigDecimal total = BigDecimal.ZERO;
        if (type == 0) {
            if (StringUtils.isEmpty(info.getAmount())) {
                accountBalance.setBalance(total);
            } else {
                total = new BigDecimal(info.getAmount());
                if (StringUtils.isNotEmpty(info.getDiscount())) {
                    total = total.add(new BigDecimal(info.getDiscount()));
                }
                accountBalance.setBalance(total);
            }
        }
        if (type == 1) {
            if (StringUtils.isEmpty(info.getCreditLimit())) {
                accountBalance.setBalance(BigDecimal.ZERO);
            } else {
                accountBalance.setBalance(new BigDecimal(info.getCreditLimit()));
            }
        }
        accountBalance.setConsumeid(info.getConsumeid());
        accountBalance.setSyscodeid(info.getSyscodeid());
        accountBalance.setSeqnum(type);
        accountBalance.setType(type);
        accountBalance.setUpdateuser(userInfo.getLoginname());
        accountBalance.setUpdateuserid(userInfo.getId());
        LOGGER_OPENORGANBIZIMPL.info("保存保存集团账本信息，syscodeid:" + info.getSyscodeid() + "账本类型:" + type);
        adminAccountBalanceService.save(accountBalance);
    }

    /**
     * 保存集团充值信息
     *
     * @param info info
     * @param userInfo userInfo
     */
    private void saveAdminRecharge(OrganManagementInfo info, AdminUser userInfo) {
        AdminRecharge adminrecharge = new AdminRecharge();
        adminrecharge.setOrganid(info.getOrganid());
        adminrecharge.setSyscodeid(info.getSyscodeid());
        adminrecharge.setAmount(new BigDecimal(info.getAmount()));
        adminrecharge.setConsumeid(info.getConsumeid());
        adminrecharge.setUpdateuser(userInfo.getLoginname());
        adminrecharge.setUpdateuserid(userInfo.getId());
        adminrecharge = adminRechargeService.save(adminrecharge);
        info.setRechargeid(adminrecharge.getId());
        LOGGER_OPENORGANBIZIMPL.info("保存集团入充值信息，syscodeid:" + info.getSyscodeid() + "充值金额：" + adminrecharge.getAmount());
    }

    /**
     * 保存集团优惠信息
     *
     * @param info info
     * @param userInfo userInfo
     */
    private void saveAdminDiscount(OrganManagementInfo info, AdminUser userInfo) {
        AdminAccountDiscount discount = new AdminAccountDiscount();
        if (null == info.getRechargeid()) {
            discount.setRechargeid(0L);
        } else {
            discount.setRechargeid(info.getRechargeid());
        }

        discount.setType(0);
        discount.setOrganid(info.getOrganid());
        discount.setSyscodeid(info.getSyscodeid());
        discount.setConsumeid(info.getConsumeid());
        discount.setAmount(new BigDecimal(info.getDiscount()));
        discount.setUpdateuser(userInfo.getLoginname());
        discount.setUpdateuserid(userInfo.getId());
        adminAccountDiscountService.save(discount);
        LOGGER_OPENORGANBIZIMPL.info("保存集团入充值优惠信息，syscodeid:" + info.getSyscodeid() + "优惠金额：" + discount.getAmount());
    }

    @Override
    public void checkShopLicence() {
        // 查询当前和续约的过期证照，续约的类型会排序到前面
        String sql = "SELECT la.id, la.syscodeid, la.matchid, la.applytype, la.shopid, lad.id ladid, lad.begindate, lad.enddate "
                + "FROM licence_apply la, licence_apply_detail lad "
                + "WHERE la.id = lad.applyid AND la.applytype <> 0 "
                + "AND la.applystatue <> 3 and lad.applystatue <> 3 AND lad.enddate <= now() ORDER BY la.applytype desc ";
        List<Map<String, Object>> result = licenceApplyService.query0(sql, new HashMap<>());
        LOGGER_OPENORGANBIZIMPL.info("过期证照总数：" + result.size());
        String id = "";
        List<Map<String, String>> renewalShopid = new ArrayList<>();
        // 店铺特征
        List<Map<String, Object>> shopsFeature = new ArrayList<>();
        // 当前和续约
        List<Map<String, Object>> shopsType = new ArrayList<>();
        // 审核当前和续约的申请，更新过期的证照
        // 按照查询排序，先检查续约的数据
        for (Iterator<Map<String, Object>> iterator = result.iterator(); iterator.hasNext(); ) {
            Map<String, Object> objectMap = iterator.next();
            try {
                shopLicence(id, objectMap, renewalShopid, shopsFeature, result);
            } catch (RuntimeException e) {
                LOGGER_OPENORGANBIZIMPL.error("店铺过期处理失败！shopid={},exception={}", objectMap.get("shopid"), e.getMessage());
                continue;
            }
        }
    }

    /**
     * @param id id
     * @param objectMap objectMap
     * @param renewalShopid renewalShopid
     * @param shopsFeature shopsFeature
     * @param result result
     */
    @Transactional
    public void shopLicence(String id, Map<String, Object> objectMap, List<Map<String, String>> renewalShopid,
                            List<Map<String, Object>> shopsFeature, List<Map<String, Object>> result) {
        // 如果和上一条的申请id不同，更新申请证照主表-设置当前审核过期
        if (!id.equals(objectMap.get("id").toString())) {
            // 如果类型是续约
            if ("2".equals(objectMap.get("applytype").toString())) {
                Map<String, String> renewal = new HashMap<>();
                renewal.put("matchid", objectMap.get("matchid").toString());
                renewal.put("syscodeid", objectMap.get("syscodeid").toString());
                renewalShopid.add(renewal);
            }

            LicenceApply licenceApply = licenceApplyService.get(new Long(objectMap.get("id").toString()));
            // 如果是审核通过的，申请状态变为过期；包括当前和续约
            if (licenceApply.getApplystatue() == 1) {
                licenceApply.setApplystatue(3);
            }
            licenceApply.setModifyDate(new Date());

            // 如果是申请类型是当前
            if ("1".equals(objectMap.get("applytype").toString())) {
                // 如果相同matchid有续约过期
                Boolean due = true;
                for (Map<String, String> renewal : renewalShopid) {
                    // 续约和当前全都过期，关闭店铺
                    if (renewal.get("matchid").toString().equals(objectMap.get("matchid").toString())) {
                        due = false;
                        // 被关闭的店铺
                        Map<String, Object> feature = new HashMap<>();
                        feature.put("syscodeid", licenceApply.getSyscodeid());
                        feature.put("matchid", licenceApply.getMatchid());
                        shopsFeature.add(feature);
                        close(feature);
                        // 更新续约为未通过
                        LicenceApply renewalLicence = licenceApplyService.get(new Long(renewal.get("syscodeid").toString()));
                        renewalLicence.setApplystatue(2);
                        renewalLicence.setModifyDate(new Date());
                        licenceApplyService.update(renewalLicence);
                        break;
                    }
                }

                // 续约没有过期的
                if (due) {
                    // 查询当前过期的申请是否存在续约成功
                    String sql2 = "matchid = #{matchid} and applytype = 2 and applystatue <> 3 ";
                    Map<String, Object> para = new HashMap<>();
                    para.put("matchid", objectMap.get("matchid"));
                    List<LicenceApply> res = licenceApplyService.selectByWhr0(sql2, para);
                    // 如果当前过期并且没有待审核的续约
                    if (res.size() == 0) {
                        // 被关闭的店铺
                        Map<String, Object> feature = new HashMap<>();
                        feature.put("syscodeid", licenceApply.getSyscodeid());
                        feature.put("matchid", licenceApply.getMatchid());
                        shopsFeature.add(feature);
                        close(feature);
                    } else {
                        // 当前过期并且有待审核或者通过审核的续约
                        for (LicenceApply apply : res) {
                            // 续约状态为待审核或者审核通过
                            if (apply.getApplystatue() == 0 || apply.getApplystatue() == 1) {
//                                    if (licenceApply.getApplystatue() == 1) {
                                // 当前更新为历史
                                licenceApply.setApplytype(0);
                                // 更新续约为当前
                                apply.setApplytype(1);
                                apply.setModifyDate(new Date());
                                licenceApplyService.update(apply);
                                LOGGER_OPENORGANBIZIMPL.info("更新续约为当前：matchid = " + apply.getMatchid());
                                break;
//                                    }
                                // 审核未通过
                            } else if (apply.getApplystatue() == 2) {
                                // 被关闭的店铺
                                Map<String, Object> feature = new HashMap<>();
                                feature.put("syscodeid", licenceApply.getSyscodeid());
                                feature.put("matchid", licenceApply.getMatchid());
                                shopsFeature.add(feature);
                                close(feature);
                                break;
                            }
                        }
                    }
                }
            } else {
                // 如果是续约，查看当前的申请有无过期
//                    List<Map<String, Object>> curr = result.stream()
//                            .filter((map) -> "1".equals(map.get("applytype").toString())
//                                    && map.get("shopid").toString().equals(objectMap.get("shopid").toString()))
//                            .collect(Collectors.toList());
                Boolean isExtst = result.stream().anyMatch(map -> "1".equals(map.get("applytype").toString())
                        && map.get("matchid").toString().equals(objectMap.get("matchid").toString()));
                if (!isExtst) {
                    // 查询当前续约有误过期的当前申请
                    String sql3 = "matchid = #{matchid} and applytype = 1 and applystatue = 3 ";
                    Map<String, Object> para = new HashMap<>();
                    para.put("matchid", objectMap.get("matchid"));
                    List<LicenceApply> res = licenceApplyService.selectByWhr0(sql3, para);
                    if (res.size() > 0) {
                        isExtst = true;
                    }
                }
                // 如果当前过期则续约变为未通过
                if (isExtst) {
                    licenceApply.setApplystatue(2);
                }
            }
            licenceApplyService.update(licenceApply);
            LOGGER_OPENORGANBIZIMPL.info("更新申请证照主表 id = " + licenceApply.getId());
        }

        // 更新申请证照明细表-设置证照过期
        LicenceApplyDetail applyDetail = licenceApplyDetailService.get(new Long(objectMap.get("ladid").toString()));
        applyDetail.setApplystatue(3);
        applyDetail.setModifyDate(new Date());
        licenceApplyDetailService.update(applyDetail);
        LOGGER_OPENORGANBIZIMPL.info("更新申请证照明细表 id = " + applyDetail.getId());
        // 下一次要比较的申请的id
        id = objectMap.get("id").toString();
    }

    /**
     * @param feature feature
     */
    private void close(Map<String, Object> feature) {
        // 关闭当前证照过期的店铺（在所有开通的平台）
        closeRelevanceShop(feature);
        // check集团店铺状态
//        checkOrganState(feature);
    }

    /**
     * 关闭当前证照过期的店铺（在所有开通的平台）
     *
     * @param feature feature
     */
    private void closeRelevanceShop(Map<String, Object> feature) {
        String sqlM = " update match_organ set disabledflag = 1 , modifydate = now() where syscodeid = #{syscodeid} and matchid = #{matchid} ";
        matchOrganService.update0(sqlM, feature);
        LOGGER_OPENORGANBIZIMPL.info("关闭店铺 match_organ, key = " + feature.get("syscodeid") + ":" + feature.get("matchid"));
        String sqlS = " update shop set disabledflag = 1 , modifydate = now() where syscodeid = #{syscodeid} and matchid = #{matchid} ";
        shopService.update0(sqlS, feature);
        LOGGER_OPENORGANBIZIMPL.info("关闭店铺 shop =, key = " + feature.get("syscodeid") + ":" + feature.get("matchid"));
    }

    /**
     * 查看是否有还开通的店铺，如果没有集团更新为关闭
     *
     * @param feature feature
     */
    private void checkOrganState(Map<String, Object> feature) {
        List<Map<String, Object>> result = adminManagementService.findOpenedShopWithOrgan(feature);
        // 如果没有开通的店铺就关闭集团
        if (Integer.valueOf(result.get(0).get("cnt").toString()) == 0) {
            matchOrganService.update0("update match_organ set disabledflag = 1, modifydate = now() where syscodeid = #{syscodeid} and type = 1",
                    feature);
            LOGGER_OPENORGANBIZIMPL.info("关闭集团 match_organ =, key = " + feature.get("syscodeid") + ":" + feature.get("matchid"));
        }
    }
}
